﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;



namespace AudiPyme.DAL
{
    public class InformesFactory
    {
        //Inserta un elemento en la tabla Informes
        public static int InsertaInforme()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            Informes nuevoInforme = new Informes();
            nuevoInforme.Fecha = DateTime.Now;
            agenteBD.AddToInformesEstablecer(nuevoInforme);
            agenteBD.SaveChanges();
            int IdInforme = nuevoInforme.IdInforme;
            return IdInforme;
        }

        //Método que inserta un Informe con el Tipo de Informe asociado según la opción elegida
        public static int InsertaInforme(String TipoInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            Informes nuevoInforme = new Informes();
            nuevoInforme.Fecha = DateTime.Now;
            nuevoInforme.TipoInforme = TipoInforme;
            agenteBD.AddToInformesEstablecer(nuevoInforme);
            agenteBD.SaveChanges();
            int IdInforme = nuevoInforme.IdInforme;
            return IdInforme;
        }

        //Método que devuelve el identificador del informe más reciente de una empresa
        public static int UltimoIdInformeEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> LIdsInformeEmpresa = (from Inf in agenteBD.InformesEstablecer
                                                  join ActInf in agenteBD.ActivosInformeEstablecer on Inf.IdInforme equals ActInf.IdInforme
                                                  join ActEmp in agenteBD.ActivosEmpresaEstablecer on ActInf.IdActivo equals ActEmp.IdActivo
                                                  where ActEmp.IdEmpresa == IdEmpresa
                                                  select Inf.IdInforme).Distinct();
            if (LIdsInformeEmpresa.Count() == 0)
            {
                //Devuelve valor centinela
                return 0;
            }
            else
            {
                List<int> LIdsInforme = LIdsInformeEmpresa.ToList();
                LIdsInforme.Sort();
                return LIdsInforme.Last();
            }
        }

        //Devuelve la fecha de cuando se creó un informe
        public static DateTime FechaInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<DateTime> FechaInf = (from Inf in agenteBD.InformesEstablecer
                                             where Inf.IdInforme == IdInforme
                                             select Inf.Fecha);
            return FechaInf.First();
        }

        //Método que elimina de forma permanente, todos los informes asociados a una empresa
        internal static void EliminaTotalInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Informes> InformesQuery = from Inf in agenteBD.InformesEstablecer
                                                 where Inf.IdInforme == IdInforme
                                                 select Inf;
            if (InformesQuery.Count() != 0)
            {
                foreach (Informes Inf in InformesQuery)
                {
                    agenteBD.InformesEstablecer.DeleteObject(Inf);
                }
                agenteBD.SaveChanges();
            }
        }

        //Método que elimina de forma física todos los informes y elementos asociados
        public static void EliminaTotalInformes(List<int> LInformes)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdInforme in LInformes)
            {
                //Vamos de las tablas exteriores a las interiores en términos de dependencia con el IdEmpresa
                //PARTE DE INFORMES
                //PlanMejora
                PlanMejoraFactory.EliminaPlanMejoraInformes(LInformes);
                //Análisis de Riesgo
                AnalisisRiesgoFactory.EliminaAnalisisRiesgoInformes(LInformes);
                //InstanciasTipoActivoAmenazaCriterioRiesgoInforme
                InstanciaTipactAmenCritriesgInformeFactory.EliminaInstanciasTipAmenCritInformes(LInformes);
                //InstanciasTipoActivoVulnerabilidadInforme
                InstanciaTipactVulnInformeFactory.EliminaInstanciasTipVulnInformeInformes(LInformes);
                //ControlesInforme
                ControlesEmpresaInformeFactory.EliminaControlesInformes(LInformes);
                //ActivosInforme
                ActivosInformeFactory.EliminaActivosInformes(LInformes);
                //EmpresaInformes
                EmpresaInformeFactory.EliminaEmpresaInformes(LInformes);
                IQueryable<Informes> InformeEliminar = from Inf in agenteBD.InformesEstablecer
                                                       where LInformes.Contains(Inf.IdInforme)
                                                       select Inf;
                foreach (Informes Informe in InformeEliminar)
                {
                    if (InformeEliminar.Count() != 0)
                    {
                        agenteBD.InformesEstablecer.DeleteObject(Informe);
                    }
                }
            }
            agenteBD.SaveChanges();
        }


        //Método que recoge el número de Informes de una Empresa
        public static int NumeroInformesEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumInformesEmpresa = (from Inf in agenteBD.InformesEstablecer
                                      join EmpInf in agenteBD.EmpresaInformeEstablecer on Inf.IdInforme equals EmpInf.IdInforme
                                      where EmpInf.IdEmpresa == IdEmpresa
                                      select Inf).Count();
            return NumInformesEmpresa;
        }

        //Devuelve el nivel de madurez actual que una empresa tiene en un informe dado
        public static int NivelMadurezActualInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> NivMadActInfQuery = from EmpInf in agenteBD.EmpresaInformeEstablecer
                                                where EmpInf.IdInforme == IdInforme
                                                select EmpInf.MadurezActualInf;
            if (NivMadActInfQuery.Count() == 0)
                return 0;
            else
                return NivMadActInfQuery.First();
        }

        //Devuelve una lista con los informes cuya fecha de creación coincida con la fecha de los parámetros
        public static List<Informes> InformesPorFecha(int IdEmpresa, int dia, int mes, int anio)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<Informes> LInformes = new List<Informes>();
            IQueryable<Informes> InformesQuery = (from i in agenteBD.InformesEstablecer
                                                  join e in agenteBD.EmpresaInformeEstablecer on i.IdInforme equals e.IdInforme
                                                  where e.IdEmpresa == IdEmpresa && i.Fecha.Day == dia && i.Fecha.Month == mes && i.Fecha.Year == anio
                                                  select i).Distinct().OrderBy(i => i.IdInforme);
            if (InformesQuery.Count() != 0)
            {
                LInformes = InformesQuery.ToList();
            }
            return LInformes;
        }

        //Recupera los informes que posee una empresa almacenados
        public static List<Informes> InformesEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<Informes> LInformes = new List<Informes>();
            IQueryable<Informes> InformesQuery = (from Inf in agenteBD.InformesEstablecer
                                                  join EmpInf in agenteBD.EmpresaInformeEstablecer on Inf.IdInforme equals EmpInf.IdInforme
                                                  where EmpInf.IdEmpresa == IdEmpresa
                                                  select Inf).OrderBy(i => i.IdInforme);
            if (InformesQuery.Count() != 0)
            {
                LInformes = InformesQuery.ToList();
            }
            return LInformes;
        }

        //Devuelve el tipo de informe de un informe dado
        public static String TipoInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> TipoInforme = (from Inf in agenteBD.InformesEstablecer
                                              where Inf.IdInforme == IdInforme
                                              select Inf.TipoInforme);
            if (TipoInforme.Count() == 0)
            {
                return "";
            }
            return TipoInforme.First();
        }
    }
}
